#ifndef GUI_H
#define GUI_H

#include <avr/pgmspace.h>
#include "Arduino.h"

#include <MemoryFree.h>


#include "utility.h";
#include "Dosing_Pumps.h";
#include "Aquarium_Devices.h";
#include "Clock.h";
#include "Temp.h";
#include "Aquarium_Modes.h";
#include "Water_Level.h";
#include "Alerts.h";

class Gui
{
public:
  typedef  enum { 
    eIDLE, eMAIN_MENU,
    eGENERAL_SETTING,eDOSING_PUMPS,eDEVICES,eMODES_SETTING,eWATER_LEVEL,eOSMOSIS_REFUL,eALERTS, // State in main menu
    eClOCK_SET,eDATE_SET,eTEMP_CALIBRATION_SELECT,eTEMP_CALIBRATION,eSTART_WAIT_SET,               // State in general setting
    eDOSING_PUMP_MENU, eDOSING_PUMP_SET, eDOSING_PUMP_GEN, eDOSING_PUMP_CALIBRATION,eDOSING_PUMP_ONE_TIME, eDOSING_PUMP_STATUS,      //    State in Dosing Pumps 
    eDEVICE_SET,                                 //  State in devices  
    eMODE_SET                                      //  State in modes
  }  
  Gui_State ;

  void Key_Press(char Key,bool hold);
  void Key_Press_Main_Up_Down(char Key, byte Menu_Len,byte Display_Num_Line);
  void Key_Press_Idel(char Key);
  void Key_Press_Main_Menu(char Key);

  void Key_Press_General_Settings(char Key);
  void Key_Press_Dosing_Pumps(char Key);
  void Key_Press_Devices(char Key);
  void Key_Press_Modes_setting(char Key);
  void Key_Press_Water_Level(char Key);
  void Key_Press_Osmosis_Refull(char Key);
  void Key_Press_Alerts(char Key);

  // General Settings manu
  void Key_Press_Clock_Set(char Key);
  void Key_Press_Date_Set(char Key);
  void Key_Press_Temp_Calibration_Select(char Key);
  void Key_Press_Temp_Calibration(char Key);
  void Key_Press_Start_Wait_Set(char Key);

  void Key_Press_Dosing_Pump_Menu(char Key);
  void Key_Press_Dosing_Pump(char Key);
  void Key_Press_Dosing_Pump_One_Time(char Key);

  void Key_Press_Device_Set(char Key);

  void Key_Press_Mode_Set(char Key);

  void Goto_Idle();
  void Goto_Main_Menu();

  void Goto_General_Settings();
  void Goto_Dosing_Pumps();
  void Goto_Devices();
  void Goto_Modes_setting();
  void Goto_Water_Level();
  void Goto_Osmosis_Refull();
  void Goto_Alerts();

  void Goto_Dosing_Pump_Menu();
  void Goto_Dosing_Pump_Gen();
  void Goto_Dosing_Pump_Set();  
  void Goto_Dosing_Pump_One_Time();
  void Goto_Dosing_Pump_Status();

  void Goto_Device_Set();

  void Goto_Mode_Set();

  void Goto_Clock_Set();
  void Goto_Date_Set();
  void Goto_Temp_Calibration_Select();
  void Goto_Temp_Calibration();
  void Goto_Start_Wait_Time_Set();



  void Print();
  void Menu_Print(  const char **menu_table , byte menu_len,  byte Display_Num_Line, byte Display_Offset  );
  void Idle_Print();
  void Main_Menu_Print();
  void General_Settings_Print();
  void Dosing_Pump_Print();
  void Dosing_Pump_One_Time_Print();
  void Device_Set_Print();
  void Mode_Set_Print();
  void Clock_Set_Print( );
  void Date_Set_Print( );
  void Temp_Calibration_Print();
  void Start_Wait_Set_Print();
  void Print_Water_Level( );
  void Print_Osmosis_Refull( );
  void Print_Alerts( );

  void Update();
private:
  byte y_position,y_offset;
  byte day_index;
  bool Reset_ask;
  
  byte temp_probe_display;
  
  byte ModeNum;
  bool MoveToModeAsk;
  
  byte hr ,  min ,  sec;
  byte mth , date , day;
  int yr;
  
  byte probe_num;
  char temp_calibration;
  bool check_horn_ask;
  byte init_start_time;

  byte Dosing_Pump_Num;
  Dosing_Pump  Temp_dosing_pump;
  byte Stirrer_Time; // in min
  byte Pump_Liquid_Amount_l;
  byte Pump_Liquid_Amount_h;
  bool One_Time_Ask;
  bool Clear_History_Ask;


  byte Device_Num;
  Aquarium_Device Temp_Aquarium_Device;

  bool  Water_Level_Save_Ask;
  bool  Water_Level_OnOff;
  byte  Water_Level_Modes;
  
  bool Osmosis_Refull_Save_Ask;
  byte Osmosis_Refull_OnOff;
  byte Osmosis_Refull_Modes;
  

  byte Number_of_Print_Alerts_Lines;


  byte Mode_Set_Num;
  byte Mode_MoveTo;
  byte Mode_MoveToAfter;
  bool Mode_SetAsk;
  Float_Mode Mode_Floats_Mode[WATER_LEVEL_NUMBER_OF_FLOATS];
  byte Float_MoveTo[WATER_LEVEL_NUMBER_OF_FLOATS];
  bool Mode_Timer_On[MODES_NUMBER_OF_TIMERS];
  byte Mode_Timer_HR[MODES_NUMBER_OF_TIMERS];
  byte Mode_Timer_MIN[MODES_NUMBER_OF_TIMERS];
  byte Mode_Timer_DAY[MODES_NUMBER_OF_TIMERS];
  byte Mode_Timer_MoveTo[MODES_NUMBER_OF_TIMERS];
  
  
  Gui_State gui_state;

};


#endif












